<html>
<head><meta charset="utf-8"><title>generic compilation speedup · t-compiler/performance · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/247081-t-compiler/performance/index.html">t-compiler/performance</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/247081-t-compiler/performance/topic/generic.20compilation.20speedup.html">generic compilation speedup</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="216736857"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/247081-t-compiler/performance/topic/generic%20compilation%20speedup/near/216736857" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Ogg <a href="https://rust-lang.github.io/zulip_archive/stream/247081-t-compiler/performance/topic/generic.20compilation.20speedup.html#216736857">(Nov 14 2020 at 16:18)</a>:</h4>
<p>Hi,<br>
I had some ideas on how to speed up generic functions &amp; types and I wanted to know what you think about. I apologize in advance if this is nonsense or if it is already done! Notice: I have more background in C++ than in Rust</p>
<p>The main problem with generic programming is that you cannot pre-compile generic functions in libraries. If every library is generic, then you are recompiling everything all the time. What I propose here is a (partial) solution to that problem.</p>
<p>As far as I understand rustc, a generic function is stored in MIR, then during monomorphization each instance get a MIR representation which is then compiled to LLVM IR.</p>
<p>Essentially, the compilation can be seen as a function <br>
F:  (MIR code of generic function, Types T1,T2,...) -&gt; LLVM IR.</p>
<p>This function can be seen as some kind of "interpreter" of the MIR code: you parse the MIR and output the corresponding LLVM codegen.</p>
<p>Here come the proposal:<br>
For a fixed generic function with MIR code called "fun", we write the function G such that<br>
G: (Types T1,....) -&gt; LLVM IR<br>
     T1,....                  -&gt; F(fun,T1,...)</p>
<p>G is a specialization of F for a specific generic function. What if we could write the function G in rust? The function could then be compiled and <em>optimized</em>! The compiled function would then be linked dynamically by the compiler (like a plugin), and be used anytime the function "fun" is used.<br>
This would mean that the function "fun" would be almost pre-compiled (only missing LLVM optimization passes), and should reduce the burden of using it greatly for the compiler. </p>
<p>I apologize if this is not entirely clear, it is hard to explain in few words (I wrote more stuff about this but for C++).</p>



<a name="216739384"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/247081-t-compiler/performance/topic/generic%20compilation%20speedup/near/216739384" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/247081-t-compiler/performance/topic/generic.20compilation.20speedup.html#216739384">(Nov 14 2020 at 17:10)</a>:</h4>
<p>While this is an interesting proposal, I don't think it will help much for rustc. I don't think there are enough opportunities to specialize on the MIR of a generic function. In addition codegen uses queries for stuff like computing type layout. Queries can't ever be inlined as the actual code is always called through a function pointer. Also the LLVM optimizations passes are responsible for a lot of the compile time.</p>
<p>Currently the goal is to reduce the amount of LLVM ir that needs to be generated by improving MIR optimizations, which run once before monomorphization. This is a lot easier than your proposal.</p>



<a name="216749225"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/247081-t-compiler/performance/topic/generic%20compilation%20speedup/near/216749225" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Ogg <a href="https://rust-lang.github.io/zulip_archive/stream/247081-t-compiler/performance/topic/generic.20compilation.20speedup.html#216749225">(Nov 14 2020 at 20:46)</a>:</h4>
<p>Thanks for the feedback!<br>
Obviously as you said some stuff could not be inlined/optimized since the types cannot be known in advance. Do you think it would represent a significant fraction of the code?<br>
Also, which fraction of the time is spent on LLVM optimization passes compared to MIR-&gt; LLVM IR? I tried finding some info on that but I came back empty ended.</p>
<p>I think I still somewhat want to have a go at that and try to hack something together that does it for a specific generic function (or generic type) and see what happens.</p>



<a name="216777561"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/247081-t-compiler/performance/topic/generic%20compilation%20speedup/near/216777561" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> lqd <a href="https://rust-lang.github.io/zulip_archive/stream/247081-t-compiler/performance/topic/generic.20compilation.20speedup.html#216777561">(Nov 15 2020 at 07:56)</a>:</h4>
<p>some LLVM module optimization is tracked in the self-profiling data under "LLVM_module_optimize". It's a superset of at least 2 other timed tasks so you'll also see these 2 in the measureme data (namely, actually running the functions and module optimization passes, the rest is setup for those, some LTO prep, and more). So on perf.rlo if you go to a perf run's result, and to its detailed query page, say <a href="https://perf.rust-lang.org/detailed-query.html?commit=75042566d1c90d912f22e4db43b6d3af98447986&amp;benchmark=style-servo-opt&amp;run_name=full">https://perf.rust-lang.org/detailed-query.html?commit=75042566d1c90d912f22e4db43b6d3af98447986&amp;benchmark=style-servo-opt&amp;run_name=full</a> you'll see that the <code>LLVM_module_optimize_module_passes</code> subtask I mentioned is taking 28% of the time here and <code>LLVM_lto_optimize</code> another 25%</p>



<a name="216777662"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/247081-t-compiler/performance/topic/generic%20compilation%20speedup/near/216777662" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> lqd <a href="https://rust-lang.github.io/zulip_archive/stream/247081-t-compiler/performance/topic/generic.20compilation.20speedup.html#216777662">(Nov 15 2020 at 07:59)</a>:</h4>
<p>in general, you'll find all this data you need starting from those profiling results. Whenever you see a query/profile label that interests you, look for that in the code: you'll see calls to the self-profiler (to "generic activities", sometimes "with args", sometimes "verbose") with those event labels and go from there</p>



<a name="216793608"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/247081-t-compiler/performance/topic/generic%20compilation%20speedup/near/216793608" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Ogg <a href="https://rust-lang.github.io/zulip_archive/stream/247081-t-compiler/performance/topic/generic.20compilation.20speedup.html#216793608">(Nov 15 2020 at 13:50)</a>:</h4>
<p>That's really interseting thanks! So if I'm reading this correctly, about half of the time is spent on LLVM optimization passes.<br>
If I understand "LLVM_module_codegen_emit_obj" and "LLVM_passes" correctly, those also happens after the transformation from MIR to LLVM IR. <br>
If we sum it up, about 75% of the time is spent <em>after</em> the transformation from MIR to LLVM, which would mean that my proposal would only help for at most the remaining 25%, meaning not much.   I wonder if this figure changes for generic/macro heavy code?</p>



<a name="216793670"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/247081-t-compiler/performance/topic/generic%20compilation%20speedup/near/216793670" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/247081-t-compiler/performance/topic/generic.20compilation.20speedup.html#216793670">(Nov 15 2020 at 13:51)</a>:</h4>
<p>for generic heavy code, <em>more</em> time is spent in llvm</p>



<a name="216793718"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/247081-t-compiler/performance/topic/generic%20compilation%20speedup/near/216793718" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/247081-t-compiler/performance/topic/generic.20compilation.20speedup.html#216793718">(Nov 15 2020 at 13:52)</a>:</h4>
<p><a href="https://github.com/rust-lang/rust/issues/78925">https://github.com/rust-lang/rust/issues/78925</a></p>



<a name="216793751"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/247081-t-compiler/performance/topic/generic%20compilation%20speedup/near/216793751" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Ogg <a href="https://rust-lang.github.io/zulip_archive/stream/247081-t-compiler/performance/topic/generic.20compilation.20speedup.html#216793751">(Nov 15 2020 at 13:53)</a>:</h4>
<p>Intersting! is it the same for macro heavy code?</p>



<a name="216793828"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/247081-t-compiler/performance/topic/generic%20compilation%20speedup/near/216793828" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/247081-t-compiler/performance/topic/generic.20compilation.20speedup.html#216793828">(Nov 15 2020 at 13:54)</a>:</h4>
<p>well it depends what the macro generates</p>



<a name="216793845"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/247081-t-compiler/performance/topic/generic%20compilation%20speedup/near/216793845" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/247081-t-compiler/performance/topic/generic.20compilation.20speedup.html#216793845">(Nov 15 2020 at 13:54)</a>:</h4>
<p><a href="#narrow/stream/247081-t-compiler.2Fperformance/topic/Slow.20Builtin.20Derives">https://rust-lang.zulipchat.com/#narrow/stream/247081-t-compiler.2Fperformance/topic/Slow.20Builtin.20Derives</a> might be interesting to read through</p>



<a name="216793854"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/247081-t-compiler/performance/topic/generic%20compilation%20speedup/near/216793854" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Ogg <a href="https://rust-lang.github.io/zulip_archive/stream/247081-t-compiler/performance/topic/generic.20compilation.20speedup.html#216793854">(Nov 15 2020 at 13:54)</a>:</h4>
<p>what is the "finish_ongoing_codegen" task?</p>



<a name="216793898"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/247081-t-compiler/performance/topic/generic%20compilation%20speedup/near/216793898" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Ogg <a href="https://rust-lang.github.io/zulip_archive/stream/247081-t-compiler/performance/topic/generic.20compilation.20speedup.html#216793898">(Nov 15 2020 at 13:55)</a>:</h4>
<p>I will have a look thanks :)</p>



<a name="216794851"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/247081-t-compiler/performance/topic/generic%20compilation%20speedup/near/216794851" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/247081-t-compiler/performance/topic/generic.20compilation.20speedup.html#216794851">(Nov 15 2020 at 14:20)</a>:</h4>
<p><code>finish_ongoing_codegen</code> waits for all background threads that are performing optimizations and the final emission of the object files.</p>



<a name="216794865"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/247081-t-compiler/performance/topic/generic%20compilation%20speedup/near/216794865" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/247081-t-compiler/performance/topic/generic.20compilation.20speedup.html#216794865">(Nov 15 2020 at 14:20)</a>:</h4>
<p><span class="user-mention" data-user-id="364324">@Ogg</span> ^</p>



<a name="216795303"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/247081-t-compiler/performance/topic/generic%20compilation%20speedup/near/216795303" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/247081-t-compiler/performance/topic/generic.20compilation.20speedup.html#216795303">(Nov 15 2020 at 14:30)</a>:</h4>
<p>pretty confusing name, "codegen" usually means translation of MIR to LLVM IR</p>



<a name="216796448"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/247081-t-compiler/performance/topic/generic%20compilation%20speedup/near/216796448" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Ogg <a href="https://rust-lang.github.io/zulip_archive/stream/247081-t-compiler/performance/topic/generic.20compilation.20speedup.html#216796448">(Nov 15 2020 at 14:50)</a>:</h4>
<p>Thanks! yeah I would never have guessed</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>